package game.gamestorage.texas.db.estimation;

import game.gamestorage.texas.db.DBProjector;

import java.util.HashMap;
import java.util.HashSet;

import util.DebugOut;
import util.sql.DBHelper;

/**
 * This class holds the statistic relevant data of a player</br>
 * one instance per player and competition<br>
 * 
 * @author Witthold/Korol
 */
public class GetterDBProjector extends DBProjector {

	/** key: id; value: String alias (playername) */
	private HashMap<Integer, String> competitonPlayers;
	private int comp_id, player_id, lastEvaledHandId;

	/*
	 * *****Cards Open*****
	 */
	/** key: hpm_id; int[0-3] position, cash_init, cash_delta, hand_id */
	private HashMap<Integer, int[]> handPlayerMapCO;
	/** hand_id, numActivePlayers */
	private HashMap<Integer, Integer> numActivePlayersCO;
	/** key: hpm_id; int[0-1] values of card */
	private HashMap<Integer, int[]> holeCards, flopCards, riverCards, turnCards;
	/** hpm_ids with associated previousActions */
	private HashMap<Integer, long[]> hpmsPreviousActionsCO;
	/** hpm_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	private HashMap<Integer, long[]> hpmsFirstBetsCO, hpmsFlopBetsCO, hpmsRiverBetsCO, hpmsTurnBetsCO;
	/** hand_ids with sb, bb, ante, finalpot */
	private HashMap<Integer, int[]> handsCO;
	/** hpm_id, hand_id */
	private HashMap<Integer, Integer> hpmHandsCO;
	/** hand_ids with round_ids, timestamp */
	private HashMap<Integer, long[]> handsFirstRoundsCO, handsFlopRoundsCO, handsRiverRoundsCO, handsTurnRoundsCO;
	/** round_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	private HashMap<Integer, long[]> roundsFirstBetsCO, roundsFlopBetsCO, roundsRiverBetsCO, roundsTurnBetsCO;

	/*
	 * *****Cards Closed*****
	 */
	/** key: hpm_id; int[0-3] position, cash_init, cash_delta, hand_id */
	private HashMap<Integer, int[]> handPlayerMapCC;
	/** hand_ids with sb, bb, ante, finalpot */
	private HashMap<Integer, int[]> handsCC;
	/** hpm_id, hand_id */
	private HashMap<Integer, Integer> hpmHandsCC;
	/** hand_ids with round_ids, timestamp */
	private HashMap<Integer, long[]> handsFirstRoundsCC, handsFlopRoundsCC, handsRiverRoundsCC, handsTurnRoundsCC;
	/** round_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	private HashMap<Integer, long[]> roundsFirstBetsCC, roundsFlopBetsCC, roundsRiverBetsCC, roundsTurnBetsCC;
	/** hpm_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	private HashMap<Integer, long[]> hpmsFirstBetsCC, hpmsFlopBetsCC, hpmsRiverBetsCC, hpmsTurnBetsCC;

	/*
	 * ***** All - closed AND open *****
	 */
	/** hpm_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	//private HashMap<Integer, long[]> hpmsFirstBetsAll;
	/** round_ids with long[] id, action, betsize, potsize, timestamp, round_id */
	private HashMap<Integer, long[]> roundsFirstBetsAll, roundsFlopBetsAll, roundsRiverBetsAll, roundsTurnBetsAll;
	/** hand_ids with round_ids, timestamp */
	private HashMap<Integer, long[]> handsFirstRoundsAll, handsFlopRoundsAll, handsRiverRoundsAll, handsTurnRoundsAll;


	/**
	 * Constructor instanciates fields
	 */
	public GetterDBProjector(int playerId, int competitionId, int lastEvaledHandId) {
		this.player_id = playerId;
		this.comp_id = competitionId;
		this.lastEvaledHandId = lastEvaledHandId;

		/* shc related fields */
		/* CO */
		numActivePlayersCO = new HashMap<Integer, Integer>();
		
		holeCards = new HashMap<Integer, int[]>();
		flopCards = new HashMap<Integer, int[]>(); 
		riverCards = new HashMap<Integer, int[]>(); 
		turnCards = new HashMap<Integer, int[]>(); 
		
		hpmsPreviousActionsCO = new HashMap<Integer, long[]>();
		hpmHandsCO = new HashMap<Integer, Integer>();
		handsFirstRoundsCO = new HashMap<Integer, long[]>();
		roundsFirstBetsCO = new HashMap<Integer, long[]>();
		hpmsFirstBetsCO = new HashMap<Integer, long[]>();
		
		handsFlopRoundsCO = new HashMap<Integer, long[]>();
		roundsFlopBetsCO = new HashMap<Integer, long[]>();
		hpmsFlopBetsCO = new HashMap<Integer, long[]>();
		
		handsRiverRoundsCO = new HashMap<Integer, long[]>();
		roundsRiverBetsCO = new HashMap<Integer, long[]>();
		hpmsRiverBetsCO = new HashMap<Integer, long[]>();
		
		handsTurnRoundsCO = new HashMap<Integer, long[]>();
		roundsTurnBetsCO = new HashMap<Integer, long[]>();
		hpmsTurnBetsCO = new HashMap<Integer, long[]>();
		/* CC */
		hpmHandsCC = new HashMap<Integer, Integer>();
		handsFirstRoundsCC = new HashMap<Integer, long[]>();
		roundsFirstBetsCC = new HashMap<Integer, long[]>();
		hpmsFirstBetsCC = new HashMap<Integer, long[]>();
		
		handsFlopRoundsCC = new HashMap<Integer, long[]>();
		roundsFlopBetsCC = new HashMap<Integer, long[]>();
		hpmsFlopBetsCC = new HashMap<Integer, long[]>();
		
		handsRiverRoundsCC = new HashMap<Integer, long[]>();
		roundsRiverBetsCC = new HashMap<Integer, long[]>();
		hpmsRiverBetsCC = new HashMap<Integer, long[]>();
		
		handsTurnRoundsCC = new HashMap<Integer, long[]>();
		roundsTurnBetsCC = new HashMap<Integer, long[]>();
		hpmsTurnBetsCC = new HashMap<Integer, long[]>();
		/* ALL */
		//hpmsFirstBetsAll = new HashMap<Integer, long[]>();
		
		init();
	}


	/*
	 * 
	 * 
	 */
	/**
	 * set HashMap competitonPlayers with all participations at this competition
	 * 
	 * @param competition_id already generated by db
	 */
	public void setCompetitionPlayers() {

		competitonPlayers = GetterQueryExecution.getPlayersInCompetition(comp_id);
	}
	
	private void init() {
		/*
		 * get hand_player_map by CO/CC
		 */
		handPlayerMapCO = DBHelper.alToHmInt(GetterQueryExecution.getHandPlayerMapsWhereEnemyCardsOpen(player_id, comp_id, lastEvaledHandId));
		handPlayerMapCC = DBHelper.alToHmInt(GetterQueryExecution.getHandPlayerMapCardsClosed(player_id, comp_id, lastEvaledHandId));
		
		/*
		 * get hands by CO/CC
		 */
		handsCO = DBHelper.alToHmInt(GetterQueryExecution.getHandsCO(player_id, comp_id, lastEvaledHandId));
		handsCC = DBHelper.alToHmInt(GetterQueryExecution.getHandsCC(player_id, comp_id, lastEvaledHandId));
	}
	
	public void upateLastEvaledHandId(int lastEvaledHandId) {
		this.lastEvaledHandId = lastEvaledHandId;
		init();
	}


	/**
	 * setPreFlopShcData
	 * set local fields by consulting DB for relevant data<br>
	 * range: max one competition, restricted by lastEvaledHandId
	 * 
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 */
	public void setPreFlopShcData() {
		/*
		 * get numActivePlayersCO
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			int num = GetterQueryExecution.getNumActivePlayers(handPlayerMapCO.get(key)[3]);
			numActivePlayersCO.put(key, num);
		}

		/*
		 * get cards
		 * TODO Performance: optimize by getting all and restrict them inside J
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			int[] cards = GetterQueryExecution.getHoleCards(key);
			holeCards.put(key, cards);
		}

		/*
		 * get firstRounds of all hands
		 */
		handsFirstRoundsAll = DBHelper.alToHmLong(GetterQueryExecution.getFirstRounds(player_id, comp_id, lastEvaledHandId));

		/*
		 * first bets of all hands by round
		 */
		roundsFirstBetsAll = DBHelper.alToHmLong(GetterQueryExecution.getFirstBetsOfRound(player_id, comp_id, lastEvaledHandId));

		/*
		 * hand_id hpm map by CO/CC
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			hpmHandsCO.put(key, handPlayerMapCO.get(key)[3]);
		}
		for (Integer key : handPlayerMapCC.keySet()) {
			hpmHandsCC.put(key, handPlayerMapCC.get(key)[3]);
		}

		/*
		 * bets of hands by CO/CC
		 */
		/*
		 * CO
		 */
		for (Integer key : handsCO.keySet()) {
			handsFirstRoundsCO.put(key, handsFirstRoundsAll.get(key));
		}
		for (Integer key : handsFirstRoundsCO.keySet()) {
			int roundId = (int) handsFirstRoundsCO.get(key)[0];
			roundsFirstBetsCO.put(roundId, roundsFirstBetsAll.get(roundId));
		}
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = hpmHandsCO.get(key);
			int rid = (int) handsFirstRoundsCO.get(hid)[0];
			hpmsFirstBetsCO.put(key, roundsFirstBetsCO.get(rid));
		}
		/*
		 * CC
		 */
		for (Integer key : handsCC.keySet()) {
			/* consider case: win by rest of players folded in last position */
			if (handsFirstRoundsAll.containsKey(key)) {
				handsFirstRoundsCC.put(key, handsFirstRoundsAll.get(key));
			}
		}
		for (Integer key : handsFirstRoundsCC.keySet()) {
			int roundId = (int) handsFirstRoundsCC.get(key)[0];
			roundsFirstBetsCC.put(roundId, roundsFirstBetsAll.get(roundId));
		}

		/*
		 * get previous actions of others
		 * for lookup in shc: numCalls, numRaises
		 * TODO try get them at once as well (bench it!)
		 */
		/* Var 1 SQL */
		for (Integer key : hpmsFirstBetsCO.keySet()) {
			if (handPlayerMapCO.get(key)[0] != 2 % numActivePlayersCO.get(key)) {
				//				DebugOut.showVerboseEstimation("position: " + handPlayerMapCO.get(key)[0]);
				//				DebugOut.showVerboseEstimation("round_id: " + hpmsFirstBetsCO.get(key)[5]);
				long[] actions = GetterQueryExecution.getPreviousActions(hpmsFirstBetsCO.get(key)[5], hpmsFirstBetsCO.get(key)[0]);
				hpmsPreviousActionsCO.put(key, actions);
			}
		}
		DebugOut.showVerboseEstimation("getStartHandData - fin");
	}


	/**
	 * setPreFlopData
	 * set local fields by consulting DB for relevant data<br>
	 * range: max one competition, restricted by lastEvaledHandId
	 * 
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 */
	public void setPreFlopData() {
		// TODO: implement that
	}


	/**
	 * setFlopData
	 * set local fields by consulting DB for relevant data<br>
	 * range: max one competition, restricted by lastEvaledHandId
	 * 
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 */
	public void setFlopData() {
		/*
		 * get flopRounds of all hands
		 */
		handsFlopRoundsAll = DBHelper.alToHmLong(GetterQueryExecution.getFlopRounds(player_id, comp_id, lastEvaledHandId));
		
		/*
		 * get cards
		 * TODO Performance: optimize by getting all and restrict them inside J
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = handPlayerMapCO.get(key)[3];
			if(handsFlopRoundsAll.containsKey(hid)) {
				int rid = (int) handsFlopRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				flopCards.put(key, cards);
			}
		}
		for (Integer key : handPlayerMapCC.keySet()) {
			int hid = handPlayerMapCC.get(key)[3];
			if(handsFlopRoundsAll.containsKey(hid)) {
				int rid = (int) handsFlopRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				flopCards.put(key, cards);
			}
		}
		
		/*
		 * flop bets of all hands by round
		 */
		roundsFlopBetsAll = DBHelper.alToHmLong(GetterQueryExecution.getFlopBetsOfRound(player_id, comp_id, lastEvaledHandId));
		

		/*
		 * bets of hands by CO/CC
		 */
		/*
		 * CO
		 */
		for (Integer key : handsCO.keySet()) {
			if(handsFlopRoundsAll.containsKey(key))
				handsFlopRoundsCO.put(key, handsFlopRoundsAll.get(key));
		}
		for (Integer key : handsFlopRoundsCO.keySet()) {
			int roundId = (int) handsFlopRoundsCO.get(key)[0];
			roundsFlopBetsCO.put(roundId, roundsFlopBetsAll.get(roundId));
		}
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = hpmHandsCO.get(key);
			if(handsFlopRoundsCO.containsKey(hid)) {
				int rid = (int) handsFlopRoundsCO.get(hid)[0];
				hpmsFlopBetsCO.put(key, roundsFlopBetsCO.get(rid));
			}
		}
		/*
		 * CC
		 */
		for (Integer key : handsCC.keySet()) {
			/* consider case: win by rest of players folded in last position */
			if (handsFlopRoundsAll.containsKey(key)) {
				handsFlopRoundsCC.put(key, handsFlopRoundsAll.get(key));
			}
		}
		for (Integer key : handsFlopRoundsCC.keySet()) {
			int roundId = (int) handsFlopRoundsCC.get(key)[0];
			roundsFlopBetsCC.put(roundId, roundsFlopBetsAll.get(roundId));
		}

		/*
		 * get previous actions of others
		 * for lookup in shc: numCalls, numRaises
		 * TODO try get them at once as well (bench it!)
		 */
		/* Var 1 SQL */
		for (Integer key : hpmsFlopBetsCO.keySet()) {
			if (handPlayerMapCO.get(key)[0] != 2 % numActivePlayersCO.get(key)) {
					DebugOut.showVerboseEstimation("position: " + handPlayerMapCO.get(key)[0]); //TODO Debug @author dgrosche
					DebugOut.showVerboseEstimation("round_id: " + hpmsFlopBetsCO.get(key)[5]); //TODO Debug @author dgrosche
				long[] actions = GetterQueryExecution.getPreviousActions(hpmsFlopBetsCO.get(key)[5], hpmsFlopBetsCO.get(key)[0]);
				hpmsPreviousActionsCO.put(key, actions);
			}
		}
		DebugOut.showVerboseEstimation("getFlopData - fin");
	}


	/**
	 * setTurnData
	 * set local fields by consulting DB for relevant data<br>
	 * range: max one competition, restricted by lastEvaledHandId
	 * 
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 */
	public void setTurnData() {
		/*
		 * get turnRounds of all hands
		 */
		handsTurnRoundsAll = DBHelper.alToHmLong(GetterQueryExecution.getTurnRounds(player_id, comp_id, lastEvaledHandId));
		
		/*
		 * get cards
		 * TODO Performance: optimize by getting all and restrict them inside J
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = handPlayerMapCO.get(key)[3];
			if(handsTurnRoundsAll.containsKey(hid)) {
				int rid = (int) handsTurnRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				turnCards.put(key, cards);
			}
		}
		for (Integer key : handPlayerMapCC.keySet()) {
			int hid = handPlayerMapCC.get(key)[3];
			if(handsTurnRoundsAll.containsKey(hid)) {
				int rid = (int) handsTurnRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				turnCards.put(key, cards);
			}
		}
		
		/*
		 * turn bets of all hands by round
		 */
		roundsTurnBetsAll = DBHelper.alToHmLong(GetterQueryExecution.getTurnBetsOfRound(player_id, comp_id, lastEvaledHandId));
		

		/*
		 * bets of hands by CO/CC
		 */
		/*
		 * CO
		 */
		for (Integer key : handsCO.keySet()) {
			if(handsTurnRoundsAll.containsKey(key))
				handsTurnRoundsCO.put(key, handsTurnRoundsAll.get(key));
		}
		for (Integer key : handsTurnRoundsCO.keySet()) {
			int roundId = (int) handsTurnRoundsCO.get(key)[0];
			roundsTurnBetsCO.put(roundId, roundsTurnBetsAll.get(roundId));
		}
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = hpmHandsCO.get(key);
			if(handsTurnRoundsCO.containsKey(hid)) {
				int rid = (int) handsTurnRoundsCO.get(hid)[0];
				hpmsTurnBetsCO.put(key, roundsTurnBetsCO.get(rid));
			}
		}
		/*
		 * CC
		 */
		for (Integer key : handsCC.keySet()) {
			/* consider case: win by rest of players folded in last position */
			if (handsTurnRoundsAll.containsKey(key)) {
				handsTurnRoundsCC.put(key, handsTurnRoundsAll.get(key));
			}
		}
		for (Integer key : handsTurnRoundsCC.keySet()) {
			int roundId = (int) handsTurnRoundsCC.get(key)[0];
			roundsTurnBetsCC.put(roundId, roundsTurnBetsAll.get(roundId));
		}

		/*
		 * get previous actions of others
		 * for lookup in shc: numCalls, numRaises
		 * TODO try get them at once as well (bench it!)
		 */
		/* Var 1 SQL */
		for (Integer key : hpmsTurnBetsCO.keySet()) {
			if (handPlayerMapCO.get(key)[0] != 2 % numActivePlayersCO.get(key)) {
					DebugOut.showVerboseEstimation("position: " + handPlayerMapCO.get(key)[0]); //TODO Debug @author dgrosche
					DebugOut.showVerboseEstimation("round_id: " + hpmsTurnBetsCO.get(key)[5]); //TODO Debug @author dgrosche
				long[] actions = GetterQueryExecution.getPreviousActions(hpmsTurnBetsCO.get(key)[5], hpmsTurnBetsCO.get(key)[0]);
				hpmsPreviousActionsCO.put(key, actions);
			}
		}
		DebugOut.showVerboseEstimation("getTurnData - fin");
	}


	/**
	 * setRiverData
	 * set local fields by consulting DB for relevant data<br>
	 * range: max one competition, restricted by lastEvaledHandId
	 * 
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 */
	public void setRiverData() {
		/*
		 * get flopRounds of all hands
		 */
		handsRiverRoundsAll = DBHelper.alToHmLong(GetterQueryExecution.getRiverRounds(player_id, comp_id, lastEvaledHandId));
		
		/*
		 * get cards
		 * TODO Performance: optimize by getting all and restrict them inside J
		 */
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = handPlayerMapCO.get(key)[3];
			if(handsRiverRoundsAll.containsKey(hid)) {
				int rid = (int) handsRiverRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				riverCards.put(key, cards);
			}
		}
		for (Integer key : handPlayerMapCC.keySet()) {
			int hid = handPlayerMapCC.get(key)[3];
			if(handsRiverRoundsAll.containsKey(hid)) {
				int rid = (int) handsRiverRoundsAll.get(hid)[0];
				int[] cards = GetterQueryExecution.getBoardCards(rid);
				riverCards.put(key, cards);
			}
		}
		
		/*
		 * flop bets of all hands by round
		 */
		roundsRiverBetsAll = DBHelper.alToHmLong(GetterQueryExecution.getRiverBetsOfRound(player_id, comp_id, lastEvaledHandId));
		

		/*
		 * bets of hands by CO/CC
		 */
		/*
		 * CO
		 */
		for (Integer key : handsCO.keySet()) {
			if(handsRiverRoundsAll.containsKey(key))
				handsRiverRoundsCO.put(key, handsRiverRoundsAll.get(key));
		}
		for (Integer key : handsRiverRoundsCO.keySet()) {
			int roundId = (int) handsRiverRoundsCO.get(key)[0];
			roundsRiverBetsCO.put(roundId, roundsRiverBetsAll.get(roundId));
		}
		for (Integer key : handPlayerMapCO.keySet()) {
			int hid = hpmHandsCO.get(key);
			if(handsRiverRoundsCO.containsKey(hid)) {
				int rid = (int) handsRiverRoundsCO.get(hid)[0];
				hpmsRiverBetsCO.put(key, roundsRiverBetsCO.get(rid));
			}
		}
		/*
		 * CC
		 */
		for (Integer key : handsCC.keySet()) {
			/* consider case: win by rest of players folded in last position */
			if (handsRiverRoundsAll.containsKey(key)) {
				handsRiverRoundsCC.put(key, handsRiverRoundsAll.get(key));
			}
		}
		for (Integer key : handsRiverRoundsCC.keySet()) {
			int roundId = (int) handsRiverRoundsCC.get(key)[0];
			roundsRiverBetsCC.put(roundId, roundsRiverBetsAll.get(roundId));
		}

		/*
		 * get previous actions of others
		 * for lookup in shc: numCalls, numRaises
		 * TODO try get them at once as well (bench it!)
		 */
		/* Var 1 SQL */
		for (Integer key : hpmsRiverBetsCO.keySet()) {
			if (handPlayerMapCO.get(key)[0] != 2 % numActivePlayersCO.get(key)) {
					DebugOut.showVerboseEstimation("position: " + handPlayerMapCO.get(key)[0]); //TODO Debug @author dgrosche
					DebugOut.showVerboseEstimation("round_id: " + hpmsRiverBetsCO.get(key)[5]); //TODO Debug @author dgrosche
				long[] actions = GetterQueryExecution.getPreviousActions(hpmsRiverBetsCO.get(key)[5], hpmsRiverBetsCO.get(key)[0]);
				hpmsPreviousActionsCO.put(key, actions);
			}
		}
		DebugOut.showVerboseEstimation("getRiverData - fin");
	}


	/*
	 * Getters
	 */

	/**
	 * @return the players
	 */
	public HashMap<Integer, String> getCompetitonPlayers() {
		return competitonPlayers;
	}


	/**
	 * @return the handPlayerMapCO
	 */
	public HashMap<Integer, int[]> getHandPlayerMapCO() {
		return handPlayerMapCO;
	}


	/**
	 * @return the numActivePlayersCO
	 */
	public HashMap<Integer, Integer> getNumActivePlayersCO() {
		return numActivePlayersCO;
	}


	/**
	 * @return the holeCards
	 */
	public HashMap<Integer, int[]> getHoleCards() {
		return holeCards;
	}
	
	/**
	 * @return the boardCards
	 */
	public HashMap<Integer, int[]> getFlopCards() {
		return flopCards;
	}


	/**
	 * @return the hpmsPreviousActionsCO
	 */
	public HashMap<Integer, long[]> getHpmsPreviousActionsCO() {
		return hpmsPreviousActionsCO;
	}


	/**
	 * @return the hpmsFirstBetsCO
	 */
	public HashMap<Integer, long[]> getHpmsFirstBetsCO() {
		return hpmsFirstBetsCO;
	}
	
	/**
	 * @return the hpmsFlopBetsCO
	 */
	public HashMap<Integer, long[]> getHpmsFlopBetsCO() {
		return hpmsFlopBetsCO;
	}
	
	/**
	 * Potsize before making a certain bet
	 * 
	 * @param bet_id which bet
	 * @return long potsize
	 */
	public long getCallSizeAtFlopCO(int hpm_id) {
		if(hpmsFlopBetsCO.containsKey(hpm_id)) {
			long bet_id = hpmsFlopBetsCO.get(hpm_id)[0];
			int hand_id = hpmHandsCO.get(hpm_id);
			int callsize = GetterQueryExecution.getCallSize(bet_id, player_id, hand_id);
			return callsize;
		} else throw new NullPointerException();
	}


	/**
	 * @return the handsCO
	 */
	public HashMap<Integer, int[]> getHandsCO() {
		return handsCO;
	}


	/**
	 * @return the handPlayerMapCC
	 */
	public HashMap<Integer, int[]> getHandPlayerMapCC() {
		return handPlayerMapCC;
	}


	/**
	 * @return the hpmsFirstBetsCC
	 */
	public HashMap<Integer, long[]> getHpmsFirstBetsCC() {
		return hpmsFirstBetsCC;
	}
	
	/**
	 * @return the hpmsFlopBetsCC
	 */
	public HashMap<Integer, long[]> getHpmsFlopBetsCC() {
		return hpmsFlopBetsCC;
	}


	/**
	 * @return the roundsFirstBetsAll
	 */
	public HashMap<Integer, long[]> getRoundsFirstBetsAll() {
		return roundsFirstBetsAll;
	}
	
	public HashMap<Integer, int[]> getAllHoleCards(int hand_id) {
		int[][] cards = GetterQueryExecution.getAllHoleCardsOfHand(hand_id);
		HashMap<Integer, HashSet<Integer>> cardList = new HashMap<Integer, HashSet<Integer>>();
		for (int i = 0; i < cards.length; i++) {
			if (cardList.containsKey(cards[i][0]))
				cardList.get(cards[i][0]).add(cards[i][1]);
			else {
				HashSet<Integer> value = new HashSet<Integer>();
				value.add(cards[i][1]);
				cardList.put(cards[i][0], value);
			}
		}
		HashMap<Integer, int[]> returnVal = new HashMap<Integer, int[]>();
		for (Integer key : cardList.keySet()) {
			int[] c2 = new int[cardList.get(key).size()];
			int i = 0;
			for (Integer next : cardList.get(key)) {
				c2[i] = next;
				i++;
			}
			returnVal.put(key, c2);
		}
		return returnVal;
	}
	
	public int getPlayerId() {
		return player_id;
	}


	public HashMap<Integer, int[]> getRiverCards() {
		return riverCards;
	}


	public HashMap<Integer,long[]> getHpmsRiverBetsCO() {
		return hpmsRiverBetsCO;
	}


	public long getCallSizeAtRiverCO(Integer hpm_id) {
		if(hpmsRiverBetsCO.containsKey(hpm_id)) {
			long bet_id = hpmsRiverBetsCO.get(hpm_id)[0];
			int hand_id = hpmHandsCO.get(hpm_id);
			int callsize = GetterQueryExecution.getCallSize(bet_id, player_id, hand_id);
			return callsize;
		} else throw new NullPointerException();
	}


	public HashMap<Integer, long[]> getHpmsTurnBetsCO() {
		return hpmsTurnBetsCO;
	}


	public HashMap<Integer, int[]> getTurnCards() {
		return turnCards;
	}


	public long getCallSizeAtTurnCO(Integer hpm_id) {
		if(hpmsTurnBetsCO.containsKey(hpm_id)) {
			long bet_id = hpmsTurnBetsCO.get(hpm_id)[0];
			int hand_id = hpmHandsCO.get(hpm_id);
			int callsize = GetterQueryExecution.getCallSize(bet_id, player_id, hand_id);
			return callsize;
		} else throw new NullPointerException();
	}

}
